package sg.edu.nus.iss.ooad.jass.ui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import sg.edu.nus.iss.ooad.jass.controller.AdvertiserController;
import sg.edu.nus.iss.ooad.jass.controller.JobAdvertisementController;
import sg.edu.nus.iss.ooad.jass.controller.JobseekerController;
import sg.edu.nus.iss.ooad.jass.controller.MainController;
import sg.edu.nus.iss.ooad.jass.entity.Advertiser;
import sg.edu.nus.iss.ooad.jass.entity.JobAdvertisement;
import sg.edu.nus.iss.ooad.jass.entity.LoginInfo;
import sg.edu.nus.iss.ooad.jass.ui.widget.AbstractJASSRegularWindow;

/**
 *
 * Main Window for JASS.
 *
 * @author Isak Rabin (HT082193M)
 * @version 1.0
 * @since 1.0
 *
 */
public class JASSAppFrame extends AbstractJASSRegularWindow {

        private final static Logger logger = Logger.getLogger(JASSAdvertisementDetailForm.class.getName());
        private final static long serialVersionUID = 5382789980908810316L;
        //Menu Components
        private MenuBar bar = null;
        private Menu systemMenu = null;
        private MenuItem loginMenuItem = null;
        private MenuItem logoutMenuItem = null;
        private Menu registerMenu = null;
        private MenuItem createJobseekerMenuItem;
        private Menu advertiserMenu = null;
        private MenuItem createAdvertMenuItem = null;
        private MenuItem updateProfileMenuItem = null;
        private Menu jobseekerMenu = null;
        private MenuItem updateJobseekerMenuItem = null;
        //Form Components
        private AdvertiserListJobAdvertisementForm jassJobAdsListPanel = null;
        //This variable will hold a reference to the main controller
        private MainController mainController = null;

        /**
         * Constructor
         */
        public JASSAppFrame(MainController mainController) {
                super("Job Advertisement and Search System", new Dimension(800, 600));
                this.mainController = mainController;
                initComponents();
                initMenu();
                resetForm();
        }

        /**
         * Intialize Form Components
         */
        private void initComponents() {
                jassJobAdsListPanel = new AdvertiserListJobAdvertisementForm("Search Job");
                jassJobAdsListPanel.addSearchActionListener(new SearchActionListener());
                jassJobAdsListPanel.addJobListItemListener(new SearchListItemListener());
                attachComponent(jassJobAdsListPanel, 1, 1, 1, 1);
        }

        /**
         * Create Application menu
         */
        public void initMenu() {
                bar = new MenuBar();

                //system sub menu
                systemMenu = new Menu("System", true);
                loginMenuItem = new MenuItem("Login");
                logoutMenuItem = new MenuItem("Logout");
                loginMenuItem.addActionListener(new LoginActionListener());
                logoutMenuItem.addActionListener(new LogoutActionListener());
                systemMenu.add(loginMenuItem);
                systemMenu.add(logoutMenuItem);
                bar.add(systemMenu);

                //register menu
                registerMenu = new Menu("Register", true);
                createJobseekerMenuItem = new MenuItem("Create Account");
                registerMenu.addActionListener(new RegisterActionListener());
                registerMenu.add(createJobseekerMenuItem);
                bar.add(registerMenu);

                setJobseekerMenu();
                setAdvertiserMenu();
                jobseekerMenu.setEnabled(false);
                advertiserMenu.setEnabled(false);


                setMenuBar(bar);
        }

        /**
         *  This operation will create Advertiser Menu
         */
        public void setAdvertiserMenu() {
                advertiserMenu = new Menu("Advertiser", true);
                createAdvertMenuItem = new MenuItem("Create Advert");
                updateProfileMenuItem = new MenuItem("Update Profile");
                createAdvertMenuItem.addActionListener(new CreateAdvertActionListener());
                updateProfileMenuItem.addActionListener(new EditAdvertiserProfileActionListener());
                advertiserMenu.add(createAdvertMenuItem);
                advertiserMenu.add(updateProfileMenuItem);
                bar.add(advertiserMenu);

        }

        /**
         *This operation will create Jobseeker Menu
         */
        public void setJobseekerMenu() {
                jobseekerMenu = new Menu("Jobseeker", true);
                updateJobseekerMenuItem = new MenuItem("Update Jobseeker");
                //add action to menu
                updateJobseekerMenuItem.addActionListener(new EditJobseekerProfileActionListener());
                jobseekerMenu.add(updateJobseekerMenuItem);
                bar.add(jobseekerMenu);
        }

        /**
         * Get menu bar. 
         * @return
         */
        @Override
        public MenuBar getMenuBar() {
                return bar;
        }

        /**
         * Reset the form
         */
        @Override
        public void resetForm() {

                //rearrange the menu
                if (LoginInfo.getLoginId() != null && !"".equalsIgnoreCase(LoginInfo.getLoginId())) {
                        loginMenuItem.setEnabled(false);
                        logoutMenuItem.setEnabled(true);
                        registerMenu.setEnabled(false);
                } else {
                        loginMenuItem.setEnabled(true);
                        logoutMenuItem.setEnabled(false);
                        registerMenu.setEnabled(true);
                }

                if (LoginInfo.isJobseeker(LoginInfo.getLoginDomain())) {
                        jobseekerMenu.setEnabled(true);
                        advertiserMenu.setEnabled(false);
                } else if (LoginInfo.isAdvertiser(LoginInfo.getLoginDomain())) {
                        jobseekerMenu.setEnabled(false);
                        advertiserMenu.setEnabled(true);
                } else if (LoginInfo.isSystemAdmin(LoginInfo.getLoginDomain())) {
                }

                searchJobAds();
        }

        /**
         * Attach the component to the form
         * @param c
         * @param gridx
         * @param gridy
         * @param gridwidth
         * @param gridheight
         * @param fill
         */
        @Override
        public void attachComponent(Component c, int gridx, int gridy, int gridwidth, int gridheight, int fill) {
                GridBagConstraints constraint = new GridBagConstraints();
                constraint.gridx = gridx;
                constraint.gridy = gridy;
                constraint.gridwidth = gridwidth;
                constraint.gridheight = gridheight;
                constraint.fill = fill;
                constraint.insets = new Insets(4, 4, 4, 4);
                constraint.weightx = 1.0;
                constraint.weighty = 1.0;
                add(c);
                GridBagLayout layout = (GridBagLayout) getLayout();
                layout.setConstraints(c, constraint);
        }

        /**
         *
         *
         * This operation will do Search based on criteria given.
         * If there is no criteria given, search result will return all
         * job advertisement.
         * 
         *
         */
        public void searchJobAds() {

                String information = "";
                List<JobAdvertisement> jobs = null;
                JobAdvertisementController jobController = null;
                AdvertiserController advertiserController = null;

                try {

                        jobs = new ArrayList<JobAdvertisement>();
                        jobController = new JobAdvertisementController();
                        advertiserController = new AdvertiserController();


                        String advertiserID = "";
                        if (LoginInfo.getLoginId() != null && LoginInfo.isAdvertiser(LoginInfo.getLoginDomain())) {
                                Advertiser advertier = advertiserController.getAdvertiserByUserID(LoginInfo.getLoginId());
                                advertiserID = advertier.getID();
                        }

                        String searchCriteria = jassJobAdsListPanel.getSearchCriteria();
                        String searchKeyword = jassJobAdsListPanel.getSearchKeyword();
                        if ("Job Key Words".equalsIgnoreCase(searchKeyword) || "".equalsIgnoreCase(searchKeyword.trim())) {
                                if ("".equalsIgnoreCase(advertiserID)) {
                                        jobs = jobController.getAllJobAdvertisement();
                                } else {
                                        jobs = jobController.findJobAdvertisementByAdvertiserID(advertiserID);
                                }
                        } else {
                                if ("By Title".equalsIgnoreCase(searchCriteria)) {
                                        information = "By Title: " + searchKeyword + ".";
                                        jobs = jobController.findJobAdvertisementByTitle(advertiserID, searchKeyword);
                                } else if ("By Skills".equalsIgnoreCase(searchCriteria)) {
                                        information = "By Skills: " + searchKeyword + ".";
                                        jobs = jobController.findJobAdvertisementBySkills(advertiserID, searchKeyword);
                                } else if ("By Company".equalsIgnoreCase(searchCriteria)) {
                                        information = "By Company: " + searchKeyword + ".";
                                        jobs = jobController.findJobAdvertisementByCompanyName(advertiserID, searchKeyword);
                                } else if ("By Job Location".equalsIgnoreCase(searchCriteria)) {
                                        information = "By Job Location: " + searchKeyword + ".";
                                        jobs = jobController.findJobAdvertisementByLocation(advertiserID, searchKeyword);
                                } else if ("By Salary (Greater or Equal)".equalsIgnoreCase(searchCriteria)) {
                                        float salary = 0f;
                                        try {
                                                salary = Float.parseFloat(searchKeyword);
                                        } catch (NumberFormatException nfx) {
                                                displayMessage("Error", nfx.getMessage());
                                                return;
                                        }
                                        information = "By Salary (Greater or Equal): " + searchKeyword + ".";
                                        jobs = jobController.findJobAdvertisementBySalary(advertiserID, salary);
                                } else if ("By Advertisement Date (n Days before)".equalsIgnoreCase(searchCriteria)) {
                                        information = "By Advertisement Date (n Days before): " + searchKeyword + ".";

                                        int nDays = 999;
                                        try {
                                                nDays = Integer.parseInt(searchKeyword);
                                        } catch (NumberFormatException nfx) {
                                                displayMessage("Error", nfx.getMessage());
                                                return;
                                        }
                                        jobs = jobController.findJobAdvertisementByAdvertisementDate(advertiserID, nDays);
                                }

                                if (jobs.isEmpty()) {
                                        displayMessage("Information", "Search return empty result");
                                }
                        }

                        jassJobAdsListPanel.setSearchInfo(information);
                        jassJobAdsListPanel.updateJobList(jobs);
                } catch (Exception e) {
                        logger.log(Level.SEVERE, null, e);
                }
        }

        /**
         * 
         * This operation will open the details for selected job advertisement
         * from list in a new window.
         *
         */
        public void viewJobAdsDetails() {
                JobAdvertisement job = null;
                try {
                        job = jassJobAdsListPanel.getSelectedJob();
                        if (job == null) {
                                return;
                        }

                        mainController.setJobAdvertisement(job);
                        mainController.setEditable(false);
                        if (LoginInfo.getLoginId() == null) {
                                mainController.gotoScreen(MainController.JASS_ADVERTISEMENT_DETAILS_FORM, this);
                        } else {
                                if (LoginInfo.isAdvertiser(LoginInfo.getLoginDomain())) {
                                        AdvertiserController advertiserController = new AdvertiserController();
                                        Advertiser loginuser = advertiserController.getAdvertiserByUserID(LoginInfo.getLoginId());
                                        if (job.getAdvertiserID().matches(loginuser.getID())) {
                                                mainController.showAdvertiserUpdateJobAdvertisementForm(this, job);
                                        } else {
                                                mainController.gotoScreen(MainController.JASS_ADVERTISEMENT_DETAILS_FORM, this);

                                        }
                                } else {
                                        mainController.gotoScreen(MainController.JASS_ADVERTISEMENT_DETAILS_FORM, null);
                                }
                        }

                } catch (Exception ex) {
                        logger.log(Level.SEVERE, ex.getMessage(), ex);
                }
        }

        /**
         * perform search action
         */
        class SearchActionListener implements ActionListener {

                public void actionPerformed(ActionEvent evt) {
                        searchJobAds();
                }
        }

        /**
         * Inner class to handle view JobAdvertisement details.
         */
        class SearchListItemListener implements ItemListener {

                public void itemStateChanged(ItemEvent e) {
                        viewJobAdsDetails();
                }
        }

        /**
         *Inner class to handle Login Action. 
         */
        class LoginActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        mainController.showLoginForm(JASSAppFrame.this);
                }
        }

        /**
         * Inner class to handle Logout Action.
         */
        class LogoutActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        LoginInfo.getInstance(null, 0);
                        resetForm();
                }
        }

        /**
         * Inner class to handle Create JobAdvertisement.
         */
        class CreateAdvertActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        //create Advert Form
                        if (LoginInfo.getLoginId() != null && LoginInfo.isAdvertiser(LoginInfo.getLoginDomain())) {
                                mainController.gotoScreen(MainController.ADVERTISER_CREATE_JOBADVERTISEMENT_FORM, JASSAppFrame.this);
                        } else {
                                mainController.gotoScreen(MainController.JASS_LOGIN_FORM, JASSAppFrame.this);
                        }

                }
        }

        /**
         * perform edit profile action
         */
        class RegisterActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        try {
                                MainController.getInstance().gotoScreen(MainController.JASS_CREATE_JOBSEEKER_FORM, JASSAppFrame.this);
                        } catch (Exception ex) {
                                logger.log(Level.SEVERE, ex.getMessage(), ex);
                        }
                }
        }

        /**
         * perform edit profile action
         */
        class EditJobseekerProfileActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        btnEditJobSeekerActionPerformed(e);
                }

                private void btnEditJobSeekerActionPerformed(ActionEvent evt) {
                        JobseekerController jobseekerController = new JobseekerController();
                        if (LoginInfo.getLoginId() != null && LoginInfo.isJobseeker(LoginInfo.getLoginDomain())) {
                                try {
                                        MainController controller = MainController.getInstance();
                                        controller.setJobSeeker(jobseekerController.getJobseekerByEmail(LoginInfo.getLoginId()));
                                        controller.setEditable(true);
                                        controller.gotoScreen(MainController.JASS_UPDATE_JOBSEEKER_FORM, JASSAppFrame.this);

                                } catch (Exception ex) {
                                        logger.log(Level.SEVERE, ex.getMessage(), ex);
                                }
                        } else {
                                MainController.getInstance().gotoScreen(MainController.JASS_LOGIN_FORM, JASSAppFrame.this);
                        }
                }
        }

        /**
         * Handle the edit advertiser profile action. 
         */
        class EditAdvertiserProfileActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        //update profile Form
                        AdvertiserController advertiserController = new AdvertiserController();
                        if (LoginInfo.getLoginId() != null && LoginInfo.isAdvertiser(LoginInfo.getLoginDomain())) {
                                try {
                                        MainController controller = MainController.getInstance();
                                        controller.setAdvertiser(advertiserController.getAdvertiserByUserID(LoginInfo.getLoginId()));
                                        controller.gotoScreen(MainController.JASS_UPDATE_ADVERTISER_FORM, JASSAppFrame.this);
                                } catch (Exception ex) {
                                        logger.log(Level.SEVERE, ex.getMessage(), ex);
                                }
                        } else {
                                MainController.getInstance().gotoScreen(MainController.JASS_LOGIN_FORM, JASSAppFrame.this);
                        }

                }
        }
}
